import datetime
import time
import numpy as np
import pymysql 
import pandas as pd
import requests
from sklearn.preprocessing import MinMaxScaler
from joblib import dump
import os

# 创建数据存储目录（如果不存在）
os.makedirs('timeing', exist_ok=True)

class WeatherUtils(object):
    """天气数据工具类"""
    def __init__(self):
        self.date_list = [
            '2024-07-01',
            '2024-08-01',
            '2024-09-01',
            '2024-10-01',
            '2024-11-01',
            '2024-12-01',
        ]
        self.url = 'http://v1.yiketianqi.com/api'
        
    def get_data(self):
        """获取天气数据并保存为CSV"""
        date_list = []
        for d in self.date_list:
            conf = {
                'appid': "76321986",  # 请替换为自己的appid
                'appsecret': "pMd7jkcR",  # 请替换为自己的appsecret（去除多余空格）
                'version': "history",
                'year': d[:4],
                'month': d[5:7],
                'city': "南昌"
            }
            try:
                # 发起请求获取数据
                res = requests.get(self.url, params=conf, timeout=10)
                res.raise_for_status()  # 检查请求是否成功
                res_data = res.json()
                
                # 检查返回数据是否包含有效信息
                if 'data' in res_data and res_data['data']:
                    for i in res_data['data']:
                        date_list.append({
                            'date': datetime.datetime.strptime(i['ymd'], '%Y-%m-%d'),
                            'bWendu': i['bWendu'],
                            'yWendu': i['yWendu'],
                            'tianqi': i['tianqi'],
                            'fengxiang': i['fengxiang'],
                            'fengli': i['fengli'],
                        })
                else:
                    print(f"获取{conf['year']}年{conf['month']}月天气数据失败：{res_data}")
                    
            except Exception as e:
                print(f"请求天气接口出错：{e}")
                continue
        
        if date_list:
            df = pd.DataFrame(date_list)
            df.to_csv('timeing/weather_data.csv', index=False)
            print(f"天气数据已保存，共{len(df)}条记录")
        else:
            print("未获取到任何天气数据")


class MysqlUtils(object):
    """MySQL数据库工具类"""
    def __init__(self):
        # 数据库连接配置（确保与实际数据库信息一致）
        self.conn = pymysql.connect(
            host='127.0.0.1',
            user='root',
            password='root',
            database='scenic1',  # 确认数据库名为scenic1（关键修正点）
            port=3306,
            charset='utf8mb4'
        )
        # 读取天气数据（确保文件存在）
        weather_path = 'timeing/weather_data.csv'
        if not os.path.exists(weather_path):
            raise FileNotFoundError(f"天气数据文件不存在，请先运行WeatherUtils获取数据：{weather_path}")
        self.weather_df = pd.read_csv(weather_path)
        
    def is_holiday(self, date):
        """判断是否为节假日（返回1是节假日，0是非节假日）"""
        # 转换日期为字符串格式进行判断
        date_str = date.strftime('%Y-%m-%d')
        holidays = [
            '2024-09-03', '2024-10-01', '2024-10-02', '2024-10-03',
            '2024-10-04', '2024-10-05', '2024-10-06', '2024-10-07',
            '2025-01-01', '2025-01-02', '2025-01-03'
        ]
        return 1 if date_str in holidays else 0
        
    def get_data(self):
        """从数据库获取数据并与天气数据合并处理"""
        try:
            with self.conn.cursor(cursor=pymysql.cursors.DictCursor) as cursor:
                # 查询订单数据（确保表名正确）
                sql = """
                SELECT DATE(g.create_time) as date, count(*) as count 
                FROM order_user_gate_rel g 
                WHERE g.create_time BETWEEN '2024-07-01' and '2025-01-01' 
                GROUP BY date
                """
                cursor.execute(sql)
                ret = cursor.fetchall()
                if not ret:
                    print("未查询到订单数据")
                    return
                
                # 转换为DataFrame并处理日期格式
                df = pd.DataFrame(ret)
                self.weather_df['date'] = pd.to_datetime(self.weather_df['date'])
                df['date'] = pd.to_datetime(df['date'])
                
                # 合并天气数据
                df_pivot = pd.merge(df, self.weather_df, on='date', how='left')
                # 处理可能的缺失值（如果天气数据有缺失）
                df_pivot = df_pivot.dropna(subset=['bWendu', 'yWendu'])
                
                # 设置日期为索引并提取时间特征
                df_pivot.set_index('date', inplace=True)
                df_pivot['dow'] = df_pivot.index.dayofweek  # 星期几（0-6）
                df_pivot['month'] = df_pivot.index.month    # 月份
                df_pivot['is_holiday'] = df_pivot.index.map(self.is_holiday)

                # 对分类特征进行独热编码
                categorical_cols = ['dow', 'month', 'tianqi', 'fengli', 'fengxiang']
                df_pivot = pd.get_dummies(df_pivot, columns=categorical_cols, dtype=int)
                
                # 处理温度数据（去除°符号并转换为整数）
                df_pivot['bWendu'] = df_pivot['bWendu'].str.replace('°', '').astype(int)
                df_pivot['yWendu'] = df_pivot['yWendu'].str.replace('°', '').astype(int)
                
                # 归一化入园数
                count_scaler = MinMaxScaler()
                df_pivot['count'] = count_scaler.fit_transform(df_pivot[['count']])
                dump(count_scaler, 'timeing/scaler.joblib')
                
                # 归一化温度特征（使用独立的归一化器）
                weather_scaler = MinMaxScaler()
                weather_features = ['bWendu', 'yWendu']
                df_pivot[weather_features] = weather_scaler.fit_transform(df_pivot[weather_features])
                dump(weather_scaler, 'timeing/weather_scaler.joblib')
               
                # 保存处理后的数据
                df_pivot.to_csv('timeing/scenic_data.csv', index=False)
                print(f"数据处理完成，共{len(df_pivot)}条记录，已保存至timeing/scenic_data.csv")
                
        except pymysql.MySQLError as e:
            print(f"数据库操作错误：{e}")
        except Exception as e:
            print(f"数据处理错误：{e}")
        finally:
            # 确保连接关闭
            self.conn.close()


if __name__ == '__main__':
    # 先获取天气数据（首次运行时需要取消注释）
    wu = WeatherUtils()
    wu.get_data()
    
    # 再从数据库获取并处理数据
    mu = MysqlUtils()
    mu.get_data()
